/*
******************************
* Copyright by Maxic Tech                                                      *
* All rights are reserved.
******************************
*/
#include "pico/stdlib.h"
#include <stdio.h>
#include <string.h>
#include "maxic_i2c.h"
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/i2c.h"

static uint8_t maxic_addr = 0x23; // 0010 0011

static int maxic_sensor_IIC_write(uint8_t addr, uint8_t reg, uint8_t val)
{
	uint8_t buf[2] = {0};
	int ret = 0;

	buf[0] = reg;
	buf[1] = val;

	ret = i2c_write_blocking(i2c_default, addr, buf, 2, false);
	printf("addr:%d,reg:%d,val:%d,ret:%d \r\n", addr, reg, val, ret);

	return ret;
}

static int maxic_sensor_IIC_Read_Byte(uint8_t addr, uint8_t reg, uint8_t *val)
{
	int ret = 0;

	i2c_write_blocking(i2c_default, addr, &reg, 1, true);
	ret = i2c_read_blocking(i2c_default, addr, val, 1, false);
	printf("addr:%d,reg:%d,val:%d,ret:%d \r\n", addr, reg, &val, ret);
	return ret;
}

static int maxic_sensor_IIC_Buffwrite(uint8_t addr, uint8_t reg, uint8_t *val, int32_t size)
{
	int ret = 0;

	i2c_write_blocking(i2c_default, addr, &reg, 1, true);
	ret = i2c_write_blocking(i2c_default, addr, val, size, false);

	return ret;
}

static int maxic_sensor_IIC_BuffRead(uint8_t addr, uint8_t reg, uint8_t *val, int32_t size)
{
	int ret = 0;

	i2c_write_blocking(i2c_default, addr, &reg, 1, true);
	ret = i2c_read_blocking(i2c_default, addr, val, size, false);

	return ret;
}

int32_t maxic_i2c_write(uint8_t reg, uint8_t val)
{
	int32_t ret;

	ret = maxic_sensor_IIC_write(maxic_addr, reg, val);
	if (ret < 0)
	{
		sleep_us(500);
		ret = maxic_sensor_IIC_write(maxic_addr, reg, val);
		if (ret < 0)
		{
			printf("maxic_i2c_write: failed to write register %x err= %d\n", reg, ret);
			// return value of negative value means failure, return value of 0 means success
		}
	}
	return ret;
}

int32_t maxic_i2c_read(uint8_t reg, uint8_t *val)
{
	int32_t ret;

	ret = maxic_sensor_IIC_Read_Byte(maxic_addr, reg, val);
	if (ret < 0)
	{
		printf("%s: failed at address %x\n", __func__, reg);
	}
	return ret; // return value of negative value means failure, return value of 1 means read one byte sucess
}

int32_t maxic_i2c_modify(uint8_t reg, uint8_t mask, uint8_t val)
{
	int32_t ret;
	uint8_t temp;

	ret = maxic_i2c_read(reg, &temp);
	// printf("%s: i2c read return value : %d \n", __func__, ret);
	//  return value of negative value means failure, return value of 1 means read one byte sucess
	temp &= ~mask;
	temp |= val;
	ret = maxic_i2c_write(reg, temp);
	// printf("%s: i2c write return value : %d \n", __func__, ret);
	//  return value of negative value means failure, return value of 0 means success

	return ret;
}

int32_t maxic_i2c_blk_read(uint8_t reg, uint8_t *val, int32_t size)
{
	int32_t ret;
	ret = maxic_sensor_IIC_BuffRead(maxic_addr, reg, val, size);
	if (ret < 0)
		printf("%s:failed at address %x (%d bytes)\n", __func__, reg, size);
	return ret; // return value of negative value means failure, return value of size means read size byte sucess
}

int32_t maxic_i2c_blk_write(uint8_t reg, uint8_t *val, int32_t size)
{
	int32_t ret;

	ret = maxic_sensor_IIC_Buffwrite(maxic_addr, reg, val, size);
	if (ret < 0)
		printf("%s: failed 2X at address %x (%d bytes)\n", __func__, reg, size);
	// return value of negative value means failure, return value of 0 means success

	return ret;
}
